import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.util.ArrayList;
import javax.swing.*;

@SuppressWarnings("serial")
public class M2ng extends JPanel {

	static int counter_combat = 0;
	public int testint;
	private JButton optionButton, continueButton, newGameButton, combatRound;
	private JTextField input_numberPlayers, input_numberOf_HumanPLayers, input_GameMode;
	private JLabel numberPlayersLabel;
	private JLabel numberOf_HumanPLayersLabel;
	private JLabel GameModeLabel;
	private JPanel veelUuem, lisa;

	boolean display_all = true; // see boolean m��rab kas nupud aeg ajalt
	// kustutatakse v�ik j��vad k�ik nupud
	// pidevalt platsi...
	public boolean debug = false;
	private Tulemus tulemus;
	private GamePanel board;
	JScrollPane scrollPane;
	public ArrayList<JButton> monsterButtons = new ArrayList<JButton>();
	private JPanel buttonPanel;
	private JLabel main_text_Label;
	private Kyssad_vazzad_paneel questionPanel;
	private HTMLtekst output;

	public M2ng() {
		setBackground(new Color(200, 200, 200));
		setLayout(new BorderLayout(3, 3));

		board = new GamePanel();
		add(board, BorderLayout.CENTER);
		buttonPanel = new JPanel();
		buttonPanel.setBackground(new Color(220, 200, 180));
		combatRound = new JButton("Combatround");
		combatRound.setEnabled(false);
		combatRound.addActionListener(board);
		buttonPanel.add(combatRound);

		continueButton = new JButton("Continue");
		continueButton.setEnabled(false);
		continueButton.addActionListener(board);
		buttonPanel.add(continueButton);

		optionButton = new JButton("Options");
		optionButton.setEnabled(true);
		optionButton.addActionListener(board);
		buttonPanel.add(optionButton);

		newGameButton = new JButton("New Game");
		newGameButton.addActionListener(board);
		buttonPanel.add(newGameButton);
		add(buttonPanel, BorderLayout.NORTH);

		Kysimused kysimuste_database = new Kysimused(true);
		kysimuste_database = kysimuste_database.loeXML_data("proov.xml", kysimuste_database);
		questionPanel = new Kyssad_vazzad_paneel(kysimuste_database, true);
		questionPanel.setBackground(new Color(170, 200, 180));
		add(questionPanel, BorderLayout.SOUTH);
		setBorder(BorderFactory.createLineBorder(new Color(130, 50, 40), 3));
	} // end constructor

	/** Tagastatakse ikoon või "null", kui ei leitud sobivat faili */
	protected static ImageIcon createImageIcon(String asukoht) {
		File f = new File(asukoht);
		if (f.exists()) {
			return new ImageIcon(asukoht);
		} else {
			System.err.println("Ei leidnud faili: " + asukoht);
			return null;
		}
	}

	/**
	 * A nested class that displays the game and does all the work of keeping
	 * track of the state and responding to user events.
	 */
	private class GamePanel extends JPanel implements ActionListener, MouseListener, MouseMotionListener,
			ComponentListener {

		public Game game = new Game();
		public int shadowlist[];
		public int shadowlist_counter;
		// public Loom rynde_loom = new Loom(null, 0, false, 0);
		public int gameOption;

		GamePanel() {
			this.addComponentListener(this);

			setLayout(new BorderLayout());
			lisa = new JPanel(new FlowLayout());
			output = new HTMLtekst();

			if (main_text_Label == null) {
				main_text_Label = new JLabel("Mingi tekst");
			} else {
				main_text_Label.setText("Mingi tekst");
			}
			add(main_text_Label, BorderLayout.NORTH);

			numberPlayersLabel = new JLabel("  Sisesta mängijate arv:");
			lisa.add(numberPlayersLabel);
			input_numberOf_HumanPLayers = new JTextField("1", 3);
			// input_numberOf_HumanPLayers.setMargin(new Insets(20, 20, 20,
			// 20));
			// input_numberPlayers.setVisible(false);
			lisa.add(input_numberOf_HumanPLayers);

			numberOf_HumanPLayersLabel = new JLabel("  Sisesta kõikide elukate arv:");
			lisa.add(numberOf_HumanPLayersLabel);
			input_numberPlayers = new JTextField("3", 3);
			// input_numberPlayers.setMargin(new Insets(20, 20, 20, 20));
			// input_numberPlayers.setVisible(false);
			lisa.add(input_numberPlayers);

			GameModeLabel = new JLabel("  Vali Game mode 0-free for all, 1 round table, 2 attack left:");
			lisa.add(GameModeLabel);
			input_GameMode = new JTextField("0", 3);
			// input_GameMode.setMargin(new Insets(20, 20, 20, 20));
			// input_numberPlayers.setVisible(false);
			lisa.add(input_GameMode, BorderLayout.WEST);
			scrollPane = new JScrollPane(lisa);
			add(scrollPane, BorderLayout.CENTER);

			addMouseListener(this);
			addMouseMotionListener(this);
			// Dimension screensize =
			// Toolkit.getDefaultToolkit().getScreenSize();
			// setPreferredSize(new Dimension(screensize.width - 300,
			// screensize.height - 300));

		} // end constructor

		public void actionPerformed(ActionEvent evt) {
			String command = evt.getActionCommand();

			if (command.equals("Options"))
				setOptions();
			else if (command.equals("New Game")) {
				// removeAll();
				doNewGame();
			} else if (command.equals("Continue")) {
				continueButton.setEnabled(false);
				ryndamine();
			} else if (command.equals("Combatround")) {
				combatRound.setEnabled(false);
				combatRound();
			} else { // we assume targeting button is pressed
				button_decoder(command);
			} // end else
		}

		void button_decoder(String command) {

			if (command.contains("6ige, j2rgmine!") || command.contains("Vale :(  Kliki siia, et minna edasi")) {
				System.out.println("Kysimus vastatud");
				questionPanel.j2rgmine.removeActionListener(board);
				questionPanel.removeAll();
				questionPanel.repaint();
				System.out.println("Listener removitud");
				tulemus.setKysimysVastatud(true);
				System.out.println("Ryndamine pärast küsimusele vastamist laks kaima");
				ryndamine();
			} 
			else {
				targeting_button_decoder(command);

				if (tulemus.isPlayer_targeting()) {
					if (tulemus.getTargeti_id() != -1) {
						System.out.println("Ryndamine laks kaima");
						ryndamine();
					}
				}
			}
		}

		void targeting_button_decoder(String command) {
			if (!display_all) {
				removeButtons();
			}
			System.out.println(tulemus.toString());
			Loom target = game.loomad.find_loom_by_id(game.loomad.find_loom_by_name(command));
			output.new_start("");

			if (tulemus.isPlayer_targeting()) {
				// kontrollime kas target on legaalne
				if (check_ohver(game.loomad.find_loom_by_name(command), tulemus.getOhvrid())) {
					shadowlist_counter++;

					if (shadowlist_counter >= shadowlist.length) { // shadowlisti
						preCombat(); // teeme uue shadowlisti
					}
					tulemus.setTargeti_id(game.loomad.find_loom_by_name(command));
				} else {
					if (tulemus.getRyndeLoom().team == target.team) {
						if (tulemus.getRyndeLoom().ID == target.ID) {
							// TODO siia vaja kirjutada et ennast rynnata ei
							// maksa
							output.new_start("Ennast rynnata ei maksa, " + target.nimi);
							main_text_Label.setText(output.getTekst());
						} else {
							output.new_start(target.nimi + "on samas teamis");
							main_text_Label.setText(output.getTekst());
						}
					} else {
						output.new_start(target.nimi + "on liiga kaugel sinust");
						main_text_Label.setText(output.getTekst());
					}
					// System.out.println ("Mittelegaalne target");
					tulemus.setTargeti_id(-1);
				}
			} else {
				// TODO siin võiks vast rohkem infot anda kui ta playereid
				// uurib
				output.new_start("See on " + target.nimi);
				main_text_Label.setText(output.getTekst());
			}
		}

		void setOptions() {
			input_numberPlayers.setVisible(true);
			input_numberPlayers.setVisible(true);
			input_numberOf_HumanPLayers.setVisible(true);
			input_GameMode.setVisible(true);
			numberPlayersLabel.setVisible(true);
			numberOf_HumanPLayersLabel.setVisible(true);
			GameModeLabel.setVisible(true);
			removeButtons();
			repaint();
		}

		private void removeButtons() {
			if (monsterButtons != null) {
				for (JButton i : monsterButtons) {
					veelUuem.remove(i);
				}
			} else
				System.out.println("Monsterbutton on null");
			monsterButtons.clear();
			repaint();
		}

		void doNewGame() {
			int i = 0;
			if (Integer.valueOf(input_numberPlayers.getText()) <= 3)
				i = 1;
			else
				i = Integer.valueOf(input_numberPlayers.getText()) / 3;
			lisa.removeAll();
			veelUuem = new JPanel(new GridLayout(i, 3));
			removeButtons();

			if (main_text_Label != null) {
				buttonPanel.remove(main_text_Label);
			}
			output.new_start("");
			questionPanel.removeAll();
			questionPanel.repaint();
			this.revalidate();

			int numberPlayers = Integer.parseInt(input_numberPlayers.getText());
			int numberHumans = Integer.parseInt(input_numberOf_HumanPLayers.getText());
			gameOption = Integer.parseInt(input_GameMode.getText());

			Kysimused kysimuste_data = new Kysimused(true);
			kysimuste_data = kysimuste_data.loeXML_data("proov.xml", kysimuste_data);

			questionPanel.kysimuste_database = kysimuste_data;

			input_numberPlayers.setVisible(false);
			input_numberOf_HumanPLayers.setVisible(false);
			input_GameMode.setVisible(false);
			numberPlayersLabel.setVisible(false);
			numberOf_HumanPLayersLabel.setVisible(false);
			GameModeLabel.setVisible(false);

			game.startNewGame(gameOption, numberPlayers, numberHumans);
			preCombat();
			shadowlist_counter = 0;
			display_targets(display_all);
			if (debug)
				combatRound.setEnabled(true);
			else
				combatRound();

			this.revalidate();
		} // end newGame();

		private void preCombat() {
			shadowlist_counter = 0;
			shadowlist = new int[game.loomad.loomad.size()];
			for (int i = 0; i < shadowlist.length; i++) {
				shadowlist[i] = game.loomad.loomad.get(i).ID;
			}
		}

		private boolean check_for_all_in_same_team() {
			int old_team = -1;
			int new_team;
			for (int i = 0; i < game.loomad.loomad.size(); i++) {
				if (i == 0)
					old_team = game.loomad.loomad.get(i).team;
				new_team = game.loomad.loomad.get(i).team;
				if (old_team != new_team) {
					return false;
				}
			}
			return true;
		}

		private void combatRound() {
			System.out.println("Combatround" + counter_combat++);
			if (check_for_all_in_same_team()) {
				declareWinners();
				return;
			}

			boolean kas_on_elus = false;
			tulemus = new Tulemus();

			if (game.loomad.find_loom_by_id(shadowlist[shadowlist_counter]) != null) {
				// kontrollime kas ryndaja on elus ja terve

				tulemus.setRyndeLoom(game.loomad.find_loom_by_id(shadowlist[shadowlist_counter]));
				kas_on_elus = true;
			}

			if (kas_on_elus == true) {

				tulemus.setSkip_this_player(false); // tegelt on tulemuse
				// contructori default false
				// nakuinii vaja leida nüüd talle sobiv ohver, ehk teeme
				// ohvrite listi,
				// kõikidest kes pole samas teamis ja ta enda ka jätame ka
				// välja

				tulemus.setOhvrid(game.loomad.find_legal_targets_for_loom(tulemus.getRyndeLoom().ID, gameOption));
				if (tulemus.getOhvrid().length > 0) {
					if (tulemus.getRyndeLoom().is_AI == true) {
						// Sobilike ohvrite nimekiri on nüüd olemas
						// AI Moment valib randomiga võimalike ohvrite
						// nimekirjast positsiooni
						tulemus.setTargeti_id(tulemus.getOhvrid()[(int) (Math.random() * tulemus.getOhvrid().length)]);
					} else {
						// loom ei ole AI, vaid player
						// output.newline();
						output.add_tekst("  Tere " + tulemus.getRyndeLoom().nimi
								+ "! Sul on võimalus rünnata järgmiseid loomi: ");
						main_text_Label.setText(output.getTekst());
						tulemus.setPlayer_targeting(true);
					}
				} else {
					output.add_tekst(tulemus.getRyndeLoom().nimi + ", You have no targets");
					main_text_Label.setText(output.getTekst());
					tulemus.setSkip_this_player(true);
				} // end else if (ohvrid.length > 0) {
			} else
				tulemus.setSkip_this_player(true);
			// end else if (kas_on_elus)
			vahepala();
		} // end combatround

		public void vahepala() {
			if (tulemus.isPlayer_targeting()) {
				// display_targets(false);
				return;
			}
			shadowlist_counter++;
			if (shadowlist_counter >= shadowlist.length) {
				preCombat(); // teeme uue shadowlisti
			}

			if (tulemus.getTargeti_id() > -1) {
				if (debug) {
					continueButton.setEnabled(true);
				} else {
					ryndamine();
				}
				return;
			}
			if (tulemus.isSkip_this_player()) {
				// do next combat round
				if (debug) {
					combatRound.setEnabled(true);
				} else
					combatRound();
			}
		} // end vahepala

		public void declareWinners() {
			if (game.loomad.loomad.size() == 1) {

				output.add_tekst(" Winner is " + game.loomad.loomad.get(0).nimi);
				if (game.loomad.loomad.get(0).is_AI == true) {

					output.add_tekst(" (AI player)");
				} else {
					output.add_tekst(" (human player)");
				}
				main_text_Label.setText(output.getTekst());

			} else {
				output.add_tekst(" Winners are: ");

				for (int playeri_ohver = 0; playeri_ohver < game.loomad.loomad.size(); playeri_ohver++) {

					output.add_tekst(" " + game.loomad.loomad.get(playeri_ohver).nimi);
				}
				main_text_Label.setText(output.getTekst());

			} // end else if if (game.loomad.loomad.size() == 1) {
		}

		public void display_targets(boolean display_all) {

			for (int playeri_ohver = 0; playeri_ohver < game.loomad.loomad.size(); playeri_ohver++) {

				display_hp(playeri_ohver, game.loomad.loomad.get(playeri_ohver).ID,
						get_suitable_hp_color(game.loomad.loomad.get(playeri_ohver).ID), 10);

				display_loom(playeri_ohver, game.loomad.loomad.get(playeri_ohver).ID);

				if (!display_all) {
					if (check_ohver(game.loomad.loomad.get(playeri_ohver).ID, tulemus.getOhvrid())) {

						enable_disable_Button(playeri_ohver, true, game.loomad.loomad.get(playeri_ohver));
					} else {

						enable_disable_Button(playeri_ohver, false, game.loomad.loomad.get(playeri_ohver));
					}

				} // end for (int playeri_ohver = 0; playeri_ohver <
				// game.loomad.loomad
			}
		} // end display_targets

		public boolean check_ohver(int id, int ohvrid[]) {

			for (int playeri_ohver = 0; playeri_ohver < ohvrid.length; playeri_ohver++) {

				if (id == ohvrid[playeri_ohver])
					return true;

			}
			return false;
		}

		public void ryndamine() {

			int hammustus_tugevus;

			if (tulemus.isKysimysVastatud()) {

				double vahemuutuja = (double) (tulemus.getRyndeLoom().dam1 * ((100.0 - (double) questionPanel.protsentarv) / 100.0));

				output.new_start(" Arvestades su " + questionPanel.protsentarv + "% vastust, ryndaja hammustusest("
						+ tulemus.getRyndeLoom().dam1 + ") on alles " + vahemuutuja + " dammu, ehk ");
				// output.newline();

				hammustus_tugevus = (int) (vahemuutuja);
				System.out.println("hammustus_tugevus =" + hammustus_tugevus);
			} else {
				hammustus_tugevus = tulemus.getRyndeLoom().dam1
						+ (int) (Math.random() * (tulemus.getRyndeLoom().dam2 - tulemus.getRyndeLoom().dam1));
			}
			output.add_tekst(tulemus.getRyndeLoom().nimi);

			Loom ohver = game.loomad.find_loom_by_id(tulemus.getTargeti_id());

			if (!ohver.is_AI) {
				// inimest r�nnatakse
				if (!tulemus.isKysimysVastatud()) {
					vasta_kysimusele(ohver);
				} else {
					elude_lahutamine(ohver, hammustus_tugevus);

					if (debug)
						combatRound.setEnabled(true);
					else
						combatRound();
				}

			} else {
				elude_lahutamine(ohver, hammustus_tugevus);
				if (debug)
					combatRound.setEnabled(true);
				else
					combatRound();
			}
		} // end ryndamine

		public void vasta_kysimusele(Loom ohver) {

			output.add_tekst(" ryndab sind. Vasta kysimusele, " + ohver.nimi);
			// output.newline();
			main_text_Label.setText(output.getTekst());
			System.out.println("Fortsykkel kaima");

			questionPanel.fortsykkel();
			questionPanel.j2rgmine.addActionListener(board);
			this.repaint();
		}

		public void elude_lahutamine(Loom ohver, int hammustus_tugevus) {

			ohver.elupunktid = ohver.elupunktid - hammustus_tugevus;
			output.add_tekst(" hammustab, " + ohver.nimi + " kaotab " + hammustus_tugevus + " elu. Alles on "
					+ ohver.elupunktid + " elu. ");
			// output.newline();
			main_text_Label.setText(output.getTekst());

			if (display_all == true) {

				display_hp(-1, ohver.ID, get_suitable_hp_color(ohver.ID), 10);
			}

			if (ohver.elupunktid <= 0) {
				output.add_tekst(ohver.nimi + " suri ära !");

				if (display_all) {
					// TODO siia peab tulema graafiline suremine
					enable_disable_Button(-1, false, ohver);
				}
				game.loomad.loomad.remove(ohver);
			} // end if (ohver.elupunktid <= 0) {
		}

		public Color get_suitable_hp_color(int looma_id) {
			Color vastus = Color.GREEN;
			Loom test_loom = game.loomad.find_loom_by_id(looma_id);
			if (test_loom.elupunktid < test_loom.max_elupunktid) {
				vastus = Color.YELLOW;
			}

			if (test_loom.elupunktid < test_loom.max_elupunktid / 2) {

				vastus = Color.ORANGE;
			}

			if (test_loom.elupunktid < test_loom.max_elupunktid / 4) {

				vastus = Color.RED;
			}
			return vastus;
		}

		public void display_hp(int button_nr, int looma_id, Color color, int border_thickness) {

			// System.out.println ("Testloom =" + test_loom.ID);
			Loom test_loom = game.loomad.find_loom_by_id(looma_id);

			// if button_nr is -1 then it means we have to find the existing
			// button, not make a new one
			JButton uus = new JButton("");

			if (button_nr == -1) {
				for (JButton i : monsterButtons) {
					if (i.getText().contains(test_loom.nimi)) {
						uus = i;
						break;
					}
				}
			} else {
				uus.setVerticalTextPosition(AbstractButton.BOTTOM);
				uus.setHorizontalTextPosition(AbstractButton.CENTER);
				uus.addActionListener(board);
				veelUuem.add(uus);
			}
			lisa.add(veelUuem);

			uus.setBorder(BorderFactory.createTitledBorder(BorderFactory.createLineBorder(color, border_thickness),
					"HP (" + test_loom.elupunktid + "/" + test_loom.max_elupunktid + ")"));
			// uus.setBorderPainted(false);
			monsterButtons.add(uus);
		}

		void enable_disable_Button(int button_nr, boolean status, Loom test_loom) {

			// if button_nr is -1 then it means we have to find the existing
			// button

			JButton uus = new JButton("");

			if (button_nr == -1) {

				for (JButton i : monsterButtons) {
					if (i.getText().contains(test_loom.nimi)) {
						uus = i;
						break;
					}
				}
				uus.setEnabled(status);
			} else {
				monsterButtons.get(button_nr).setEnabled(status);
			}
		}

		public void display_loom(int button_nr, int looma_id) {

			Loom test_loom = game.loomad.find_loom_by_id(looma_id);
			// System.out.println ("Testloom =" + test_loom.ID);
			// CropImageVer2 crop = new CropImageVer2();
			// crop.cropImage(test_loom.getType()+".gif",
			// test_loom.getType()+"_medium.gif", 250, 250);
			// System.out.println(buttonPanel.getSize());

			// J2rgnevat koodi kasutame dynaamilisuse lisamiseks m2ngule
			if (buttonPanel.getWidth() < 700) {

				// pisikesed pildid
				monsterButtons.get(button_nr).setIcon(
						createImageIcon("images/loomad_indrek/tiny/" + test_loom.getType() + ".gif"));

			} else if (buttonPanel.getWidth() >= 700 && buttonPanel.getWidth() < 1000) {

				// keskmised pildid
				monsterButtons.get(button_nr).setIcon(
						createImageIcon("images/loomad_indrek/medium/" + test_loom.getType() + ".gif"));
			}

			else if (buttonPanel.getWidth() >= 1000) {
				monsterButtons.get(button_nr).setIcon(
						createImageIcon("images/loomad_indrek/" + test_loom.getType() + ".gif"));
			}

			else {
				System.out.println("error, midagi on pahasti...pildi 6ige suuruse valimisel");
			}

			// monsterButtons.get(button_nr).setSize(30, 30);
			monsterButtons.get(button_nr).setVisible(true);
			/*
			 * monsterButtons.get(button_nr).setOpaque(false);
			 * monsterButtons.get(button_nr).setContentAreaFilled(false);
			 */
			monsterButtons.get(button_nr).setText(test_loom.nimi);

		} // end display_loom

		/**
		 * The paint method shows the message at the bottom of the canvas, and
		 * it draws all of the dealt cards spread out across the canvas.
		 */
		public void paintComponent(Graphics g) {
			super.paintComponent(g); // fill with background color.
		} // end paintComponent();

		@Override
		public void mouseClicked(MouseEvent arg0) {
		}

		public void mouseEntered(MouseEvent arg0) {
		}

		@Override
		public void mouseExited(MouseEvent evt) {
		}

		public void mousePressed(MouseEvent evt) {
		}

		@Override
		public void mouseReleased(MouseEvent evt) {
		}

		@Override
		public void mouseDragged(MouseEvent evt) {
		}

		@Override
		public void mouseMoved(MouseEvent evt) {
		}

		@Override
		public void componentHidden(ComponentEvent arg0) {
		}

		@Override
		public void componentMoved(ComponentEvent arg0) {
		}

		@Override
		public void componentResized(ComponentEvent arg0) {
			removeButtons();
			display_targets(display_all);
		}

		@Override
		public void componentShown(ComponentEvent arg0) {
		}

	} // end nested class GamePanel

} // end class LoomadGameGUI
